package com.yc.cloud.common.basic.exception;


import com.yc.cloud.common.basic.api.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 全局异常处理
 * Created by macro on 2020/2/27.
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(value = ApiException.class)
    public ResponseResult<String> handle(ApiException e) {
        if (e.getErrorCode() != null) {
            return ResponseResult.failed(e.getErrorCode());
        }
        return ResponseResult.failed(e.getMessage());
    }

    // 捕获所有 RuntimeException
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public ResponseResult<String> handleRuntimeException(RuntimeException ex) {
        // 打印日志
        log.error("Caught RuntimeException: ", ex);
        return ResponseResult.failed(ex.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseResult<String> handleValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField() + fieldError.getDefaultMessage();
            }
        }
        return ResponseResult.validateFailed(message);
    }


    @ResponseBody
    @ExceptionHandler(value = BindException.class)
    public ResponseResult<String> handleValidException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField() + fieldError.getDefaultMessage();
            }
        }
        return ResponseResult.validateFailed(message);
    }

    @ResponseBody
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public ResponseResult<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException ex, WebRequest request) {
        String message = ex.getMessage();
        String dynamicMessage = "Invalid input.";

        // 检查是否是枚举类型转换失败引发的异常
        if (message != null && message.contains("not one of the values accepted for Enum class")) {
            dynamicMessage = extractEnumErrorMessage(message);
        }
        // Log the full exception if necessary
        // log.error("HttpMessageNotReadableException: ", ex);

        return ResponseResult.validateFailed(dynamicMessage);
    }

    // 从异常消息中提取并构建有用的错误信息
    private String extractEnumErrorMessage(String message) {
        // 正则表达式提取枚举类型和值信息
        Pattern pattern = Pattern.compile("Cannot deserialize value of type `[^`]+` from String \"([^\"]+)\": not one of the values accepted for Enum class: \\[([^\\]]+)\\]");
        Matcher matcher = pattern.matcher(message);
        if (matcher.find()) {
            String invalidValue = matcher.group(1);
            String acceptedValues = matcher.group(2);
            return String.format("Invalid value '%s' for enum. Accepted values are: [%s].", invalidValue, acceptedValues);
        }
        return "Invalid enum value.";
    }
}
